package com.gitee.l0km.xthrift.service;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;

import org.apache.thrift.protocol.TProtocol;

import com.facebook.nifty.core.ConnectionContext;
import com.facebook.nifty.core.RequestContext;
import com.google.common.collect.Maps;

/**
 * 用于将{@link RequestContext}重新封装<br>
 * 参考 {@link com.facebook.nifty.core.NiftyRequestContext}实现
 * @author guyadong
 * @since 1.3.0
 *
 */
public class XThriftRequestContext implements RequestContext {
    private final ConnectionContext connectionContext;
    private final TProtocol inputProtocol;
    private final TProtocol outputProtocol;
    private final ConcurrentMap<String, Object> data = Maps.newConcurrentMap();

    public XThriftRequestContext(RequestContext requestContext, TProtocol inputProtocol,
    		TProtocol outputProtocol) {
    	if(null != requestContext) {
    		this.connectionContext = requestContext.getConnectionContext();
    		for(Iterator<Entry<String, Object>> itor = requestContext.contextDataIterator();itor.hasNext();) {
    			Entry<String, Object> entry = itor.next();
    			data.put(entry.getKey(), entry.getValue());
    		}
    	}else {
    		this.connectionContext = null;
		}
    	this.inputProtocol = inputProtocol;
    	this.outputProtocol = outputProtocol;
    }

	@Override
    public TProtocol getInputProtocol()
    {
        return inputProtocol;
    }

    @Override
    public TProtocol getOutputProtocol()
    {
        return outputProtocol;
    }

    @Override
    public ConnectionContext getConnectionContext()
    {
        return connectionContext;
    }

    @Override
    public void setContextData(String key, Object val)
    {
        checkNotNull(key, "context data key is null");
        data.put(key, val);
    }

    @Override
    public Object getContextData(String key)
    {
        checkNotNull(key, "context data key is null");
        return data.get(key);
    }

    @Override
    public void clearContextData(String key)
    {
        checkNotNull(key, "context data key is null");
        data.remove(key);
    }

    @Override
    public Iterator<Map.Entry<String, Object>> contextDataIterator()
    {
        return Collections.unmodifiableSet(data.entrySet()).iterator();
    }

}
